package edu.amm.fanal.api;

/**
 * Преобразование линейной задачи.
 * 
 * @author Иванов Илья
 * @since 2013-05-11
 *
 */
public abstract class Transformation {
	
	/** Исходная задача. */
	protected LinearProblem sourceProblem;
	
	private LinearProblem transformed;
	
	/**
	 * @param sourceProblem Исходная задача.
	 */
	public Transformation(LinearProblem sourceProblem) {
		if (sourceProblem == null)
			throw new RuntimeException("Не задана исходная задача для преобразования");
		
		this.sourceProblem = sourceProblem;
	}
	
	/**
	 * Выполняет преобразование.
	 * 
	 * @return Преобразованная задача.
	 */
	public LinearProblem getTransformed() {
		if (transformed != null)
			return transformed;
		
		return transformed = transform();
	}
	
	/**
	 * Восстанавливает решение исходной задачи по решению преобразованной задачи.
	 * 
	 * @param solution Решение преобразованной задачи.
	 * @return Решение исходной задачи.
	 */
	public Function restoreSolution(Function solution) {
		if (solution == null)
			throw new RuntimeException("Не задано решение преобразованной задачи");
		
		return restore(solution);
	}
	
	/**
	 * Выполняет преобразование.
	 * 
	 * @return Преобразованная задача.
	 */
	protected abstract LinearProblem transform();
	
	/**
	 * Восстанавливает решение исходной задачи по решению преобразованной задачи.
	 * 
	 * @param solution Решение преобразованной задачи.
	 * @return Решение исходной задачи.
	 */
	protected abstract Function restore(Function solution);
}